﻿package com.duartepeixinho.rotation
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	/**
	 * ...
	 * @author Duarte Peixinho
	 */
	public class Main extends Sprite 
	{
		private var _line:baseLine = new baseLine();
		private var _ball:ball = new ball();
		private const GRAVITY:Number = 0.9;	
		private var _ballDragging:Boolean = false;
		
		private var oldX:Number = 0;
		private var oldY:Number = 0;
		private var throwX:Number = 0;
		private var throwY:Number = 0;
		
		private const FRICTION:Number = 0.96;
		
		public function Main() {
			init();
			
			addEventListener(Event.ENTER_FRAME, loop);			
		}
	
		private function ballClicked(e:MouseEvent):void {
			_ball.startDrag();
			_ball.vx = 0;
			_ball.vy = 0;
			_ballDragging = true;
		}
		private function ballUnclicked(e:MouseEvent):void {
			_ball.stopDrag();
			_ballDragging = false;
			_ball.vx += throwX;
			_ball.vy += throwY;
			trace(throwX);
		}
	
		private function init():void {
			_ball.x = stage.stageWidth / 2;
			_ball.y = _ball.height / 2;
			oldX = _ball.x;
			oldY = _ball.y;
			addChild(_ball);
			_line.x = stage.stageWidth / 2;
			_line.y = stage.stageHeight * 3 / 4;
			addChild(_line);		
			
			_ball.addEventListener(MouseEvent.MOUSE_DOWN, ballClicked);
			_ball.addEventListener(MouseEvent.MOUSE_UP, ballUnclicked);
		}
		
		private function loop(e:Event):void {
			_line.rotation = (mouseX - stage.stageWidth) / 6 + 70;
			
			//ball physics
			if (!_ballDragging) {
				_ball.vy += GRAVITY;
				_ball.vy += _ball.ay;
				_ball.vx += _ball.ax;
				
				_ball.vx *= FRICTION;
				_ball.vy *= FRICTION;
			}
			else {
				throwX = _ball.x - oldX;
				throwY = _ball.y - oldY;
				oldX = _ball.x;
				oldY = _ball.y;
			}			
			
			_ball.x += _ball.vx;
			_ball.y += _ball.vy;
			
			
			//bounce in the walls
			if (_ball.y - _ball.height / 2 < 0) {
				_ball.y = _ball.height / 2;
				_ball.vy *= _ball.bounce;
			}
			if (_ball.y + _ball.height / 2 > stage.stageHeight) {
				_ball.y = stage.stageHeight - _ball.height / 2;
				_ball.vy *= _ball.bounce;
			}
			if (_ball.x - _ball.width / 2 < 0) {
				_ball.x = _ball.width / 2;
				_ball.vx *= _ball.bounce;		
			}
			if (_ball.x + _ball.width / 2 > stage.stageWidth) {
				_ball.x = stage.stageWidth - _ball.width / 2;
				_ball.vx *= _ball.bounce;
			}			
			verifyCollision();
		}
		
		private function verifyCollision():void {
			//calculate the angle
			var angle:Object = Rotation2D.calcAngle(_line.rotation * Math.PI / 180);
			
			// get position of ball, relative to line
			var x:Number = _ball.x - _line.x;
			var y:Number = _ball.y - _line.y;
			
			// rotate line
			var rotateBallFromLine:Point = Rotation2D.rotateValues(new Point(x, y), angle, true);
			
			// rotate velocity
			var rotateVelocity:Point = Rotation2D.rotateValues(new Point(_ball.vx, _ball.vy), angle, true);
			
			// perform bounce with rotated values
			var bounds:Rectangle = _line.getBounds(this);
			if(rotateBallFromLine.y > -_ball.height / 2 && (_ball.x > (_line.x - bounds.width/2) && _ball.x < (_line.x + bounds.width/2)))
			{
				rotateBallFromLine.y = -_ball.height / 2;
				rotateVelocity.y *= _ball.bounce * 2;
			}
			
			// rotate everything back
			var rotateBackBallFromLine:Point = Rotation2D.rotateValues(new Point(rotateBallFromLine.x, rotateBallFromLine.y), angle);

			var rotateBackVelocity:Point = Rotation2D.rotateValues(new Point(rotateVelocity.x, rotateVelocity.y), angle);
			
			_ball.vx = rotateBackVelocity.x;
			_ball.vy = rotateBackVelocity.y;
			
			// reset actual ball position
			_ball.x = _line.x + rotateBackBallFromLine.x;
			_ball.y = _line.y + rotateBackBallFromLine.y;
		}
	}	
}